package com.zang.im.croom.netty.handler;

import com.zang.im.croom.netty.processor.WebSocketProcessor;
import com.zang.im.croom.netty.common.SSGlobalConstMap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * @author Zhang Qiang
 * @Date 2019/7/27 17:06
 */
@Slf4j
@Component
@Sharable
public class WsJsonMsgHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
    /**
     * 所有链接
     */
    private Map<String, Channel> channelMap = SSGlobalConstMap.getChannelMap();

     /**
      * 处理类分发器
      */
    @Autowired
    private WebSocketProcessor socketProcessor;

     /**
      * 连接添加
      */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        String longId = ctx.channel().id().asLongText();
        channelMap.put(longId, ctx.channel());
    }

    /**
      * 解析WebSocket
      */
    @Override
    protected void messageReceived(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {

        log.info("socketProcessor : " + socketProcessor);
        socketProcessor.handler(ctx, channelMap, msg);
    }

    /**
      * 断开时删除
      */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        dropChannel(ctx);
    }

     /**
      * 异常
      */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        String excMsg = "Connection reset by peer";
        if(excMsg.equalsIgnoreCase(cause.getMessage())){
            log.error("连接被重置");
        }
        log.warn("连接出现问题");
        dropChannel(ctx);
        ctx.close();
    }

     /**
      * 从map删除通道
      */
    private void dropChannel(ChannelHandlerContext ctx){
        channelMap.entrySet().stream().filter(entry -> entry.getValue() == ctx.channel()).forEach(entry -> channelMap.remove(entry.getKey()));
    }



}
